# pip install fastapi uvicorn redis[asyncio]

from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException, Depends
import redis.asyncio as redis

# Redis连接配置（生产环境建议放入.env）
REDIS_URL = "redis://192.168.43.123:6379"

# 全局Redis连接池
redis_pool: redis.Redis | None = None


# 生命周期管理（替代on_event）
@asynccontextmanager
async def lifespan(app: FastAPI):
    global redis_pool
    # 启动时创建连接池
    redis_pool = redis.from_url(
        REDIS_URL,
        decode_responses=True,  # 自动解码为字符串
        max_connections=10,  # 连接池大小
        socket_timeout=5  # 5秒超时
    )
    print("✅ Redis连接池已初始化")
    yield
    # 关闭时释放连接
    await redis_pool.close()
    print("🛑 Redis连接池已关闭")


app = FastAPI(lifespan=lifespan)


# 依赖注入：获取Redis客户端
async def get_redis() -> redis.Redis:
    return redis_pool


# 测试接口
@app.get("/ping")
async def ping(redis_client: redis.Redis = Depends(get_redis)):
    return {"status": await redis_client.ping()}  # 返回PONG说明连接正常


# 健康检测
@app.get("/health")
async def health_check(redis_client: redis.Redis = Depends(get_redis)):
    try:
        await redis_client.ping()
        return {"status": "ok"}
    except:
        raise HTTPException(500, detail="Redis连接失败")


# 存储数据
@app.post("/set/{key}")
async def set_value(key: str, value: str, redis_client: redis.Redis = Depends(get_redis)):
    await redis_client.set(key, value, ex=3600)  # 设置60秒过期
    return {"message": f"已存储: {key}={value}"}


# 读取数据
@app.get("/get/{key}")
async def get_value(key: str, redis_client: redis.Redis = Depends(get_redis)):
    value = await redis_client.get(key)
    if not value:
        raise HTTPException(404, detail="Key不存在")
    return {"key": key, "value": value}


# 删除数据
@app.delete("/del/{key}")
async def del_value(key: str, redis_client: redis.Redis = Depends(get_redis)):
    if await redis_client.delete(key) == 0:
        raise HTTPException(404, detail="Key不存在")
    return {"message": f"已删除: {key}"}


if __name__ == "__main__":
    import uvicorn

    uvicorn.run("main:app", host='127.0.0.1', port=8000, log_level="info", reload=True)
